import io
import os
import pathlib
import traceback
from pathlib import Path as lPath
import h5py

import sanic.server.websockets.connection
from PIL import Image
from datetime import datetime
from sanic import response

ROOT = lPath('/OMSDATA-TW2')


def gen_img_path(data_path: str, frm_no: str) -> pathlib.Path:
  return lPath(data_path) / frm_no


async def thumb(request, raw, tool, **kwargs):
  a = request.args
  jn = gen_img_path(a.f, a.n)
  if jn.exists():
    with Image.open(jn) as img, io.BytesIO() as o:
      img.thumbnail((256, 192))
      img.save(o, format='jpeg')
      b = o.getvalue()

  return raw(b, status=200, content_type='image/jpeg')


def frm_img(request, file, **kw):
  a = request.args
  f = gen_img_path(a.f, a.n)
  return file(f)


async def tasks(request, json, tool, **kw):
  args = request.args
  a, b = args.ins.split('/')
  day = args.day.replace('-', '')
  files = glob.glob(f'/OMSDATA-TW2/OriginalData/*/{b}/{day}*/{a}')
  files.sort()
  return json(files)


async def frames(request, text, **kwargs):
  a = request.args
  with open(f'{a.f}/.info', 'r', encoding='utf8') as f:
    return text(f.read())


async def realtime(request, ws, redis, **kwargs):
  import rt_msg
  ins = request.args.ins
  ws.ins = ins
  await rt_msg.notify.add_ws(ws, redis)
  try:
    while True: await ws.recv()
  finally:
    await ws.close()
    rt_msg.notify.rm(ws)


import numpy


async def rt(request, ws, **kwargs):
  a = request.args
  jn = gen_img_path(a.f, a.n).with_suffix('.tif')
  im = numpy.array(Image.open(jn))
  while True:
    pos = await ws.recv()
    try:
      x, y = pos.split(',')
      x, y = int(x), int(y)
      print(f'图像值 {"*" * 100}')
      print(f'shape:{im.shape},d.dtype:{im.dtype},im.ndim:{im.ndim}')
      ndim = im.ndim
      if ndim == 2:
        r = f"Gray: {im[y,x]}"
      if ndim==3:
        r = 'R:%d,G:%d,B:%d' % tuple(im[y, x])
    except:
      print(pos)
      ws.close()
      traceback.print_exc()

    else:
      await ws.send(str(r))


import glob


async def download(request, raw, **kw):
  args = request.args
  ipth = gen_img_path(args.f, args.n)
  f = ipth.with_suffix(args.t)
  size = f.stat().st_size
  if not f.exists(): return response.empty(status=404)
  print(f'file size is {size}')
  filename = f'{f.parent.parent.name}_{args.n}_{datetime.now().strftime("%Y%m%d%H%M%S")}{args.t}'
  headers = {
    "Content-Disposition": f'attachment; filename="{filename}"'
  }
  if request.method == 'HEAD':
    return response.empty(status=200, headers=headers)
  return response.raw(f.read_bytes(), status=200, headers=headers, content_type="application/octet-stream")


def dld(request, **kw):
  a = request.args
  path = (lPath(a.t) / a.n).resolve()
  return response.file_stream(path, filename=path.name, chunk_size=0x10000)


import re

'''磁强计图表类仪器历史任务'''


async def tasklist(request, json, **kw):
  """根据日期、站点、仪器获取任务列表
  1. 无日期，最后一天任务
  2. 无站点，所有站点
  """
  root = '/OMSDATA-TW2/OriginalData/GRAS'
  args = request.args
  sta = args.get('sta', '*')
  ins = args.get('ins')
  day = args.get('t', None)
  if not day:

    l = glob.glob(f'{root}/{sta}/*/{ins}')
    print(l)
    if not l:
      return json({})
    # ROOT.as_posix()
    l.sort(reverse=True)
    match = re.search(r'(?P<y>\d{4})(?P<m>\d{2})(?P<d>\d{2})-', str(l[0]))
    print(match)
    if match:
      day = f"{match.group('y')}-{match.group('m')}-{match.group('d')}"
      dfilter = f"{match.group('y')}{match.group('m')}{match.group('d')}"
    else:
      dfilter = day = ''
    task_fs = [i for i in l if dfilter in i]
    print(task_fs)
    return json({"t": day, "tasks": list(task_fs)})
  dpth = day.replace('-', '')
  l = glob.glob(f"{root}/{sta}/{dpth}-*/{ins}", recursive=True)
  return json({"t": day, "tasks": list(l)})


async def amag(request, json, **kw):
  import h5py
  from datetime import datetime, timedelta
  f = '/OMSDATA-TW2/20240115/GRAS1-00001/AMAG/data.h5'
  with h5py.File(f, 'r') as tf:
    for k, d in tf.items():
      ax, s, v = d.shape


def downf(request, file, **kw):
  path = f'{request.args.f}/*{request.args.m}'
  return file(path, )


# async def h5data(request, raw, **kw):
#   t = request.args.t
#   r = request.args.n
#   with h5py.File(f'{t}/.h5', 'r') as f:
#     return raw(f[r][:].tobytes())


async def bindata(request, raw, **kw):
  t = request.args.t
  n = request.args.n or ''
  offset = int(request.args.offset)
  size = int(request.args.size)
  with open(f'{t}/{n}.dat', 'rb') as f:
    f.seek(offset, 0)
    return raw(f.read(size))


class D(dict):
  __getattr__ = dict.__getitem__
  __setattr__ = dict.__setitem__
  __delattr__ = dict.__delitem__

  def __missing__(self, key):
    return None


async def canpa(request, raw, json, **kw):
  import matplotlib
  from json import loads
  matplotlib.use('Agg')
  t = request.args.t
  slice = request.args.slice
  m = request.args.mode
  t_start = float(request.args.s or 1e9) // 1000 - 1
  t_end = float(request.args.e or 1e16) // 1000 + 2
  s = 0
  e = 0
  indexs = []
  idx,dtype = {
    'gia': (0, [('离子能量', '8192f4')]),
    'tia': (1, [('能量', '90f4'), ('俯仰角', '15f4'), ('质量组', '9f4'), ('方位角', '24f4')]),
    'tea': (2, [('能量', '96f4'), ('俯仰角', '15f4'), ('方位角', '24f4')]),
    'sia': (3, [('C1能道', '144f4'), ('C2能道', '144f4'), ('C3能道', '144f4'), ('C4能道', '144f4')]),
  }[m]

  with open(f'{t}/.info', 'r', encoding='utf8') as f:
    info = [loads(i, object_hook=D) for i in f]
    n=0
    print(f'canpa {"*"*50}')
    for i,x in enumerate(info[1:]):

      if x.frm[idx]:
        if x.st < t_start:
          pass
        elif x.st < t_end:
           indexs.append(n)
        else:
          break
        # indexs.append(n)
        n+=1

  ar = numpy.fromfile(f'{t}/{m}.dat', dtype=dtype)
  print(f'ar.shape:{ar.shape}, indexs.len:{len(indexs)}')
  ar = ar[indexs]
  fs, fe = 0, ar.shape[0]
  names = ar.dtype.names
  title = {'gia': '气体与离子分析仪', 'tia': '热离子分析仪', 'tea': '热电子分析仪', 'sia': '太阳风离子分析仪'}[m]
  # time = (numpy.array(time) + 8 * 3600).astype('M8[s]')  # + 8 * 3600  # timestamp - bjt
  from matplotlib import pyplot as plt, dates, colors
  # t_num = time
  plt.rcParams['font.sans-serif'] = ['WenQuanYi Micro Hei', 'DejaVu Sans Display', 'WenQuanYi Zen Hei']
  H = 6
  W = 8
  fig = plt.figure(figsize=[8, 6])
  N = len(names)
  axs = []
  cax = []
  H1 = H - 0.5
  P = 0.2
  B = 0.5
  h = H1 / N
  hh = (h - P) / H
  for i in range(N):
    axs.append(plt.axes([0.05, (B + i * h) / H, 0.85, hh], sharex=axs[0] if axs else None))
    cax.append(plt.axes([0.92, (B + i * h) / H, 0.03, hh]))
  axs[-1].set_title(f'{title} {m.upper()}')
  for n, ax, ca in zip(names[::-1], axs, cax):
    d = ar[n].T
    h, w = d.shape
    if m == 'gia':
      norm = colors.PowerNorm(0.5)
      ss, ee, vv = (int(v) for v in slice.split(','))
      d = [d[i:min(i + vv, ee)].sum(axis=0) for i in range(ss, ee, vv)]
    else:
      ss, ee = 0, h
      norm = None
    m = ax.imshow(d, cmap='jet',
                  origin='lower',
                  extent=[fs, fe, ss, ee],
                  norm=norm,  # interpolation='hamming',
                  aspect='auto')
    # ax.xaxis_date()
    ax.set_ylabel(n)
    plt.colorbar(m, cax=ca)
  # axs[0].set_xlabel('时间/(BJT)')
  for i in axs[1:]: plt.setp(i.get_xticklabels(), visible=False)
  with io.BytesIO() as f:
    fig.savefig(f, format='jpeg', dpi=200, bbox_inches='tight', pad_inches=0.2)
    return raw(f.getvalue(), headers={'content-type': 'image/jpeg', })
